from flask import Flask, render_template, request, jsonify, session, redirect, url_for
import pickle
import numpy as np
import os

app = Flask(__name__)
app.secret_key = os.urandom(24)  # 设置密钥用于session

# 加载模型，(系数, 截距)的元组
with open('model.pkl', 'rb') as f:
    model_data = pickle.load(f)
model_coef, model_intercept = model_data

# 假设的基准分和比例因子
BASE_SCORE = 600
SCALE = 50

# 用户认证
VALID_USERS = {
    "123456": "123456",
    "user09": "password09"
}

@app.route('/')
def index():
    # 检查用户是否已登录
    if 'username' not in session:
        return redirect(url_for('login'))
    return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        data = request.get_json()
        username = data.get('username')
        password = data.get('password')
        
        # 验证用户凭据
        if username in VALID_USERS and VALID_USERS[username] == password:
            session['username'] = username
            return jsonify({'success': True, 'message': '登录成功'})
        else:
            return jsonify({'success': False, 'message': '用户名或密码错误'})
    
    return render_template('login.html')

@app.route('/logout', methods=['POST'])
def logout():
    session.pop('username', None)
    return jsonify({'success': True})

@app.route('/predict', methods=['POST'])
def predict():
    # 检查用户是否已登录
    if 'username' not in session:
        return jsonify({'success': False, 'message': '未登录'})
    
    # 检查模型是否加载成功
    if model_coef is None:
        return jsonify({'success': False, 'message': '模型加载失败'})
    
    try:
        # 获取前端发送的数据
        data = request.get_json()
        
        # 提取模型需要的5个特征（根据模型训练时的特征顺序）
        features = [
            float(data.get('RevolvingUtilizationOfUnsecuredLines', 0)),
            float(data.get('age', 0)),
            float(data.get('NumberOfTime30-59DaysPastDueNotWorse', 0)),
            float(data.get('NumberOfTimes90DaysLate', 0)),
            float(data.get('NumberOfTime60-89DaysPastDueNotWorse', 0))
        ]
        
        # 转换为numpy数组并调整形状
        features_array = np.array(features).reshape(1, -1)
        
        # 使用模型进行预测
        logit_score = np.dot(features_array, model_coef.T) + model_intercept
        probability = 1 / (1 + np.exp(-logit_score))
        
        # 计算信用分
        credit_score = BASE_SCORE + SCALE * logit_score
        
        # 判断是否为失信用户（违约概率大于0.5）
        is_delinquent = bool(probability > 0.5)
        
        # 返回结果
        return jsonify({
            'success': True,
            'credit_score': float(credit_score),
            'default_probability': float(probability),
            'is_delinquent': is_delinquent
        })
        
    except Exception as e:
        return jsonify({'success': False, 'message': f'预测错误: {str(e)}'})

if __name__ == '__main__':
    app.run(debug=True)